package domain

import (
	"github.com/lab-online/internal/shared/code"
	"github.com/lab-online/internal/user/constant"
	"github.com/lab-online/internal/user/entity"
	"github.com/lab-online/pkg/auth"
)

func (d *Domain) AddUser(newUser entity.UserEntity, authEntity auth.AuthEntity) (entity.UserEntity, error) {
	isHigherRole := authEntity.IsTeacher() && (newUser.IsTeacher() || newUser.IsAdmin())
	if isHigherRole {
		return nil, constant.RESTErrNoPermissionCreate
	}

	savedUser, dbErr := d.repository.GetUnscopedUserByUsername(newUser.GetUsername())
	if savedUser != nil {
		if !savedUser.GetDeletedAt().Valid {
			return nil, constant.RESTErrUserAlreadyExists
		}

		newUser.Update(
			entity.WithID(savedUser.GetID()),
			entity.WithDeletedAt(savedUser.GetDeletedAt()),
		)
	} else if dbErr != nil && code.IsEqual(dbErr, code.DatabaseUnknownError) {
		return nil, dbErr
	}

	if err := newUser.HashPassword(); err != nil {
		return nil, constant.RESTErrPasswordHashError
	}

	return d.repository.SaveUser(newUser)
}
